package com.t.bricks.bussiness.service.flowwork.impl;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.t.bricks.bussiness.db.dao.flowwork.FlowWorkNodeDao;
import com.t.bricks.bussiness.db.entity.flowwork.FlowWorkNode;
import com.t.bricks.bussiness.service.flowwork.FlowWorkNodeService;
import com.t.bricks.model.MsgEmity;
import com.t.bricks.utils.function.data.IntegerUtil;
import com.t.bricks.utils.function.date.TimeUtil;
import com.t.bricks.utils.spring.ModuleUtil;

/**
 * 流程实例节点'FlowWorkNode表'基本业务操作类接口实现
 * @author HuangXinBian
 * @DateTime 2022年01月26日 15:18:58
 */
@Service
public class FlowWorkNodeServiceImpl implements FlowWorkNodeService<FlowWorkNode> {
	
	@Autowired
	private FlowWorkNodeDao<FlowWorkNode> flowWorkNodeDao;

	/**
	 * 修改指定节点内容描述
	 * @param uId
	 * @param iVersion
	 * @param sDescription
	 * @return
	 */
	@Override
	public MsgEmity editDescription(String uId, Integer iVersion, String sDescription) {
		if (null == uId || "".equals(uId.trim())) {
			return MsgEmity.err(8001, "节点编号不能为空");
		}

		if (null == iVersion || iVersion.intValue() < 1) {
			return MsgEmity.err(8002, "节点版本号必须大于0");
		}
		
		uId = uId.trim();
		
		MsgEmity me = this.findById(uId, false);
		if (!me.isSuccess()) {
			return MsgEmity.err(8003, "没有找到对应节点信息");
		}
		
		FlowWorkNode flowWorkNode = me.getData();
		
		if (flowWorkNode.getiState().intValue() != 2) {
			return MsgEmity.err(8004, "只有执行中的节点才能进行修改");
		}
		
		if (flowWorkNode.getiVersion().intValue() != iVersion) {
			return MsgEmity.err(8005, "待执行的节点记录版本不一致,可能已经被修改");
		}
		
		if (!IntegerUtil.contain(flowWorkNode.getiType(), new int[] {1, 6})) {
			return MsgEmity.err(8006, "起点和终点不能进行修改");
		}

		if (flowWorkNode.getiType().intValue() == 2
				&& flowWorkNode.getsCreator() != ModuleUtil.currentLoginUserId()) {
			return MsgEmity.err(8007, "发起节点的描述只有发起者能修改");
		}

		if (flowWorkNode.getiType().intValue() != 2
				&& null != flowWorkNode.getsNodeUsers()
				&& !"".equals(flowWorkNode.getsNodeUsers().trim())
				&& !flowWorkNode.getsNodeUsers().contains(ModuleUtil.currentLoginUserId())) {
			return MsgEmity.err(8008, "当前节点限定了操作人员");
		}
		
		sDescription = null == sDescription ? null : sDescription.trim();
		
		me = this.callMapping("editDescription", uId, iVersion, sDescription);
		if (!me.isSuccess()) {
			return me;
		}
		
		int i = me.getData();
		if (i > 0) {
			return MsgEmity.success(8999, "更新节点内容描述成功");
		}
		
		me = this.findById(uId, false);
		if (!me.isSuccess()) {
			return me;
		}
		
		flowWorkNode = me.getData();
		if (flowWorkNode.getiState().intValue() != 2) {
			return MsgEmity.err(8009, "只有执行中的节点才能进行修改,可能节点已经被其他人操作");
		}

		if (flowWorkNode.getiVersion().intValue() != iVersion) {
			return MsgEmity.err(8010, "待执行的节点记录版本不一致,可能刚刚被修改");
		}
		
		return MsgEmity.err(8011, "未知的情况发生,请刷新数据后重试");
	}

	/**
	 * 审批节点
	 * @param uId
	 * @param iVersion
	 * @param sAuditing 审批意见
	 * @param iSuccess 审批通过(布尔值,1:是)
	 * @return
	 */
	@Override
	public MsgEmity auditing(String uId, Integer iVersion, String sAuditing, Integer iSuccess) {
		if (null == uId || "".equals(uId.trim())) {
			return MsgEmity.err(8001, "节点编号不能为空");
		}

		if (null == iVersion || iVersion.intValue() < 1) {
			return MsgEmity.err(8002, "节点版本号必须大于0");
		}
		
		uId = uId.trim();
		
		MsgEmity me = this.findById(uId, false);
		if (!me.isSuccess()) {
			return MsgEmity.err(8003, "没有找到对应节点信息");
		}
		
		FlowWorkNode flowWorkNode = me.getData();
		
		if (flowWorkNode.getiState().intValue() != 2) {
			return MsgEmity.err(8004, "只有执行中的节点才能进行修改");
		}
		
		if (flowWorkNode.getiVersion().intValue() != iVersion) {
			return MsgEmity.err(8005, "待执行的节点记录版本不一致,可能已经被修改");
		}
		
		if (!IntegerUtil.contain(flowWorkNode.getiType(), new int[] {1, 6})) {
			return MsgEmity.err(8006, "起点和终点不能进行修改");
		}

		if (flowWorkNode.getiType().intValue() == 2
				&& flowWorkNode.getsCreator() != ModuleUtil.currentLoginUserId()) {
			return MsgEmity.err(8007, "发起节点的描述只有发起者能修改");
		}

		if (flowWorkNode.getiType().intValue() != 2
				&& null != flowWorkNode.getsNodeUsers()
				&& !"".equals(flowWorkNode.getsNodeUsers().trim())
				&& !flowWorkNode.getsNodeUsers().contains(ModuleUtil.currentLoginUserId())) {
			return MsgEmity.err(8008, "当前节点限定了操作人员");
		}
		
		//--判断类型--//
		switch (flowWorkNode.getiType().intValue()) {//类型(枚举,1:起点;2:发起者;3:过程(任意通过);4:过程(一票否决);5:结束)
		case 1:
			return MsgEmity.err(8021, "起点不能进行修改");
		case 2:
			return MsgEmity.err(8022, "发起节点的审批意见不能进行修改");
		case 3:
			return auditingType3(flowWorkNode, sAuditing, iSuccess);
		case 4:
			return auditingType4(flowWorkNode, sAuditing, iSuccess);
		case 5:
			return MsgEmity.err(8021, "终点不能进行修改");
		default:
			break;
		}
		
		
		sAuditing = null == sAuditing ? null : sAuditing.trim();
		
		me = this.callMapping("auditing", uId, iVersion, sAuditing);
		if (!me.isSuccess()) {
			return me;
		}
		
		int i = me.getData();
		if (i > 0) {
			return MsgEmity.success(8999, "更新节点内容描述成功");
		}
		
		me = this.findById(uId, false);
		if (!me.isSuccess()) {
			return me;
		}
		
		flowWorkNode = me.getData();
		if (flowWorkNode.getiState() != 2) {
			return MsgEmity.err(8009, "只有执行中的节点才能进行修改,可能节点已经被其他人操作");
		}

		if (flowWorkNode.getiState() != 2) {
			return MsgEmity.err(8010, "待执行的节点记录版本不一致,可能刚刚被修改");
		}
		
		return MsgEmity.err(8011, "未知的情况发生,请刷新数据后重试");
	}
	
	/**
	 * 处理类型3的节点
	 * 过程(任意通过):只要有一个审批人通过则可以通过
	 * @param flowWorkNode
	 * @return
	 */
	private MsgEmity auditingType3(FlowWorkNode flowWorkNode, String sAuditing, Integer iSuccess) {
		String nowUserId = ModuleUtil.currentLoginUserId();
		String sNodeUsers = flowWorkNode.getsNodeUsers();
		
		if (null != sNodeUsers && !"".equals(sNodeUsers.trim()) && !sNodeUsers.contains(nowUserId)) {
			return MsgEmity.err(8031, "当前节点限定了操作人员");
		}
		
		if (flowWorkNode.getsExecuteUsers().contains(nowUserId)) {
			return MsgEmity.err(8032, "已经执行过了");
		}
		
		String nowUserName = ModuleUtil.currentLoginUserName();
		String sExecuteUsers = flowWorkNode.getsExecuteUsers() + ";" + nowUserId;
		if (sExecuteUsers.startsWith(";")) {
			sExecuteUsers = sExecuteUsers.substring(1);
		}

		String sExecuteUserNames = flowWorkNode.getsExecuteUserNames() + ";" + nowUserName;
		if (sExecuteUserNames.startsWith(";")) {
			sExecuteUserNames = sExecuteUserNames.substring(1);
		}
		
		String setsExecuteTimes = flowWorkNode.getsExecuteTimes() + ";" + TimeUtil.nowDateTime();
		if (setsExecuteTimes.startsWith(";")) {
			setsExecuteTimes = setsExecuteTimes.substring(1);
		}
		
		flowWorkNode.setsExecuteUsers(sExecuteUsers);//执行用户(分号分隔)
		flowWorkNode.setsExecuteUserNames(sExecuteUserNames);//执行用户名称(分号分隔)
		flowWorkNode.setsExecuteTimes(setsExecuteTimes);//执行时间(分号分隔)
		flowWorkNode.setsAuditing(sAuditing);//审批意见
		flowWorkNode.setiSuccess((1 == iSuccess) ? 1 : 2);//审批通过(布尔值,1:是)
		
		//审批不通过,并且还有其他人可以操作时,继续保持
		if ((1 != iSuccess) && (sNodeUsers.length() > setsExecuteTimes.split(";").length)) {
			MsgEmity me = flowWorkNodeDao.editNode(flowWorkNode);//只修改节点信息
			if (!me.isSuccess()) {
				return me;
			}
		}
		
		//审批不通过,并且其他人也没有通过(因为一旦有通过的就已经不会再执行了)
		if ((1 != iSuccess) && (sNodeUsers.length() <= setsExecuteTimes.split(";").length)) {
			flowWorkNode.setiState(3);//状态(枚举,1:待执行;2:执行中;3:审核完毕;4:任务执行失败;5:已完结)
			
			return flowWorkNodeDao.auditing(flowWorkNode);//操作数据库,不管是否成功都要结束
		}
		
		//审批通过(一旦有通过的就已经审批结束)
		flowWorkNode.setiState(3);//状态(枚举,1:待执行;2:执行中;3:审核完毕;4:任务执行失败;5:已完结)
		return flowWorkNodeDao.auditing(flowWorkNode);//操作数据库,不管是否成功都要结束
	}
	
	/**
	 * 处理类型4的节点
	 * 过程(一票否决):只要有一个审批人不通过则可以通过
	 * @param flowWorkNode
	 * @param sAuditing
	 * @param iSuccess
	 * @return
	 */
	private MsgEmity auditingType4(FlowWorkNode flowWorkNode, String sAuditing, Integer iSuccess) {
		String nowUserId = ModuleUtil.currentLoginUserId();
		String sNodeUsers = flowWorkNode.getsNodeUsers();
		
		if (null != sNodeUsers && !"".equals(sNodeUsers.trim()) && !sNodeUsers.contains(nowUserId)) {
			return MsgEmity.err(8031, "当前节点限定了操作人员");
		}
		
		if (flowWorkNode.getsExecuteUsers().contains(nowUserId)) {
			return MsgEmity.err(8032, "已经执行过了");
		}
		
		String nowUserName = ModuleUtil.currentLoginUserName();
		String sExecuteUsers = flowWorkNode.getsExecuteUsers() + ";" + nowUserId;
		if (sExecuteUsers.startsWith(";")) {
			sExecuteUsers = sExecuteUsers.substring(1);
		}

		String sExecuteUserNames = flowWorkNode.getsExecuteUserNames() + ";" + nowUserName;
		if (sExecuteUserNames.startsWith(";")) {
			sExecuteUserNames = sExecuteUserNames.substring(1);
		}
		
		String setsExecuteTimes = flowWorkNode.getsExecuteTimes() + ";" + TimeUtil.nowDateTime();
		if (setsExecuteTimes.startsWith(";")) {
			setsExecuteTimes = setsExecuteTimes.substring(1);
		}
		
		flowWorkNode.setsExecuteUsers(sExecuteUsers);//执行用户(分号分隔)
		flowWorkNode.setsExecuteUserNames(sExecuteUserNames);//执行用户名称(分号分隔)
		flowWorkNode.setsExecuteTimes(setsExecuteTimes);//执行时间(分号分隔)
		flowWorkNode.setsAuditing(sAuditing);//审批意见
		flowWorkNode.setiSuccess((1 == iSuccess) ? 1 : 2);//审批通过(布尔值,1:是)
		
		//审批通过,并且还有其他人可以操作时,继续保持
		if ((1 == iSuccess) && (sNodeUsers.length() > setsExecuteTimes.split(";").length)) {
			MsgEmity me = flowWorkNodeDao.editNode(flowWorkNode);//只修改节点信息
			if (!me.isSuccess()) {
				return me;
			}
		}
		
		//审批通过,并且全员通过(因为一旦有不通过的就已经不会再执行了)
		if ((1 == iSuccess) && (sNodeUsers.length() <= setsExecuteTimes.split(";").length)) {
			flowWorkNode.setiState(3);//状态(枚举,1:待执行;2:执行中;3:审核完毕;4:任务执行失败;5:已完结)
			
			return flowWorkNodeDao.auditing(flowWorkNode);//操作数据库,不管是否成功都要结束
		}
		
		//审批不通过(一旦有通过的就已经审批结束)
		flowWorkNode.setiState(3);//状态(枚举,1:待执行;2:执行中;3:审核完毕;4:任务执行失败;5:已完结)
		return flowWorkNodeDao.auditing(flowWorkNode);//操作数据库,不管是否成功都要结束
	}
	
	/**
	 * 查询实例下的所有节点
	 * @param sWorkId 所属实例编号
	 * @return MsgEmity 返回查询结果
	 */
	@Override
	public MsgEmity findByWork(String sWorkId) {
		if (null == sWorkId || "".equals(sWorkId.trim())) {
			return MsgEmity.err(8001, "流程实例编号不能为空");
		}
		
		MsgEmity me = this.callMapping("findByWork", sWorkId, ModuleUtil.currentLoginUserId());
		if (!me.isSuccess()) {
			return MsgEmity.err(8002, "查询实例下的所有节点失败");
		}
		
		return me;
	}
	
}
